package sn;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import sn.functions.ActivationFunction;

public class Neuron {
	private ActivationFunction activationFunction;
	private List<Double> weights;
	private double sigma;
	private List<Double> lastInput;
	private double lastSum;

	public Neuron(ActivationFunction transferFunction) {
		this.activationFunction = transferFunction;
	}
	
	public Neuron(ActivationFunction transferFunction, List<Double> weights) {
		this.activationFunction = transferFunction;
		this.weights = weights;
	}

	public void connect(int inputNeuronCount) {
		weights = new ArrayList<Double>();
		for(int i = 0; i < inputNeuronCount; i++){
			weights.add(Math.random());
		}
	}

	public double compute(List<Double> list) {
		double sum = 0.0;
		for(int i = 0; i < list.size(); i++){
			sum += weights.get(i) * list.get(i);
		}
		lastInput = list;
		lastSum = sum;
		return activationFunction.compute(sum);
	}
	
	public void increaseSigma(double element){
		sigma+=element;
	}
	
	public double getSigma(){
		return sigma;
	}
	
	public double getWeight(int index){
		return weights.get(index);
	}

	public void eraseSigma() {
		sigma = 0.0;
	}

	public void updateWeights() {
		for(int i = 0; i < weights.size(); i++){
			double newWeight = weights.get(i) + sigma * activationFunction.derivative(lastSum) * lastInput.get(i);
			weights.set(i, newWeight);
		}
		eraseSigma();
	}
	
	@Override
	public String toString(){
		if (weights != null){
			StringBuilder sb = new StringBuilder();
			DecimalFormat df = new DecimalFormat("#.##");
			sb.append("Neuron: {");
			for (Double w : weights){
				sb.append(df.format(w)).append(" ");
			}
			sb.append("}\n");
			return sb.toString();
		}
		return "InputNeuron\n";
	}
	
}
